/*
 * created on Nov 30, 2009
 */
package top.v5it.japi.ddd.core.xml;

import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.nio.file.Files;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * search and read file with java.io.File
 *
 * @author fangang
 */
@Slf4j
public class FileResource implements Resource, ResourcePath {

    private File file;
    private Filter filter = null;

    /**
     * @return the file
     */
    public File getFile() {
        return file;
    }

    /**
     * @param file the file to set
     */
    public void setFile(File file) {
        this.file = file;
    }

    /**
     * Default constructor
     */
    public FileResource() {
        super();
    }

    /**
     * Constructor for file
     *
     * @param file
     */
    public FileResource(File file) {
        super();
        this.file = file;
        log.debug("loading " + this.getDescription());
    }

    /**
     * read files with the code <code>new FileInputStream(file)</code>,
     * and return null if it is a directory.
     *
     * @return InputStream
     * @throws IOException
     */
    @Override
    public InputStream getInputStream() throws IOException {
        File file = this.getFile();
        if (file == null || file.isDirectory()) {
            return null;
        }
        Filter filter = this.getFilter();
        if (filter != null && !filter.isSatisfied(file.getName())) {
            return null;
        }
        return Files.newInputStream(file.toPath());
    }

    /**
     * get all of the files in the path with the method <code>File.listFiles()</code>
     *
     * @return Resource[]
     * @throws IOException
     */
    @Override
    public Resource[] getResources() throws IOException {
        File file = this.getFile();
        if (file == null) {
            return null;
        }
        if (file.isDirectory()) {
            File[] files = file.listFiles();
            Filter filter = this.getFilter();
            List<FileResource> fileLoaders = new ArrayList<FileResource>();
            for (int i = 0; i < Objects.requireNonNull(files).length; i++) {
                if (filter != null && !filter.isSatisfied(files[i].getName())) {
                    continue;
                }
                fileLoaders.add(new FileResource(files[i]));
            }
            return fileLoaders.toArray(new Resource[0]);
        }
        Resource resource = new FileResource(file);
        resource.setFilter(this.getFilter());
        return new Resource[]{resource};
    }

    @Override
    public String getDescription() {
        try {
            return "FileResource:[file:" +
                    this.getFile().getCanonicalPath() + "]";
        } catch (IOException e) {
            return "";//throw new RuntimeException(e);
        }
    }

    @Override
    public Filter getFilter() {
        return this.filter;
    }

    @Override
    public void setFilter(Filter filter) {
        this.filter = filter;
    }

    @Override
    public String getFileName() {
        if (this.getFile() == null) {
            return null;
        }
        String fileName = this.getFile().getName();
        if (fileName.regionMatches(0, "\\", 0, 2))
            fileName = fileName.replaceAll("\\", "/");
        return fileName;
    }
}
